﻿using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Xml;
using feather.attr;
using feather.core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NVelocity;
using NVelocity.App;

namespace feather.unit
{
    public class FormActionUnit
    {
        /// <summary>
        /// 提取集合中的对象
        /// </summary>
        /// <param name="map">集合</param>
        /// <param name="key">对象名称</param>
        /// <param name="def">默认值</param>
        /// <returns></returns>
        [ActionMethod]
        public object mapGetString(IDictionary<string, object> map, string key, [InputParam("default")] string def)
        {
            object result = null;
            if(map.TryGetValue(key, out result))
                return result;
            return def;
        }

        /// <summary>
        /// 格式化字符串
        /// </summary>
        /// <param name="template">格式化模板</param>
        /// <param name="args">格式化参数</param>
        /// <returns></returns>
        [ActionMethod]
        public object formatString(string template, [InputParam("params")] object args)
        {
            VelocityEngine vltEngine = new VelocityEngine();
            vltEngine.Init();
            
            VelocityContext vltContext = new VelocityContext();

            if (args is IDictionary<string, object>)
            {
                IDictionary<string, object> o = args as IDictionary<string, object>;
                foreach (KeyValuePair<string, object> e in o)
                {
                    vltContext.Put(e.Key, e.Value);
                }
            }
            else if (args is JObject)
            {
                JObject o = args as JObject;
                foreach (KeyValuePair<string, JToken> e in o)
                {
                    object val = (e.Value as JValue).Value;
                    vltContext.Put(e.Key, val);
                }
            }
            StringWriter stringWriter = new StringWriter();
            if(vltEngine.Evaluate(vltContext, stringWriter, "feather", template))
                return stringWriter.ToString();
            return string.Empty;
        }

        /// <summary>
        /// 使用XPath表达式获取数据
        /// </summary>
        /// <param name="xml">XML数据</param>
        /// <param name="xpath">XPath</param>
        /// <returns></returns>
        [ActionMethod]
        public object xmlPath(string xml, string xpath)
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(xml);

            XmlNodeList xmlNodeList = xmlDocument.SelectNodes(xpath);
            return xmlNodeList.Item(0).InnerText;
        }

        /// <summary>
        /// 打开/执行指定的文件
        /// </summary>
        /// <param name="path">文件路径</param>
        [ActionMethod]
        public void openFile(string path)
        {
            if (path != null)
                Process.Start(path);
        }

        /// <summary>
        /// 将对象转换成Json字符串
        /// </summary>
        /// <param name="json">需要转换的对象</param>
        /// <returns></returns>
        [ActionMethod]
        public string jsonToString(object json)
        {
            return JsonConvert.SerializeObject(json);
        }

        /// <summary>
        /// 将Json字符串转换成对象
        /// </summary>
        /// <param name="str">需要转换Json字符串</param>
        /// <returns></returns>
        [ActionMethod]
        public object stringToJson(string str)
        {
            return JsonConvert.DeserializeObject(str);
        }

        /// <summary>
        /// 为DataTable增加一列（方式1:使用表达式，方式2:使用Action结果）
        /// </summary>
        /// <param name="dataTable">DataTable对象</param>
        /// <param name="columnName">列名（1,2）</param>
        /// <param name="expression">列表达式（1）</param>
        /// <param name="action">列执行Action（2）</param>
        /// <param name="mapping">Action参数映射（2）</param>
        /// <param name="actionController">Action控制器（2）</param>
        /// <returns></returns>
        [ActionMethod]
        public DataTable dataTableAddColumn(DataTable dataTable, string columnName, string expression, string action, IDictionary<string, object> mapping, ActionController actionController)
        {
            if (expression != null)
            {
                dataTable.Columns.Add(columnName, typeof(string), expression);
            }
            else if (action != null)
            {
                dataTable.Columns.Add(columnName);

                IDictionary<string, object> actionParams = new Dictionary<string, object>();

                foreach (DataRow dataRow in dataTable.Rows)
                {
                    actionParams.Clear();

                    foreach (KeyValuePair<string, object> e in mapping)
                    {
                        actionParams.Add(e.Key, dataRow[e.Value as string]);
                    }
                    dataRow[columnName] = actionController.DoURI(action, actionParams);
                }

            }
            
            return dataTable;
        }
    }
}
